package net.ib.mtalk.ui.favorite;

import java.util.ArrayList;
import java.util.List;

import net.ib.mntalk.protocol.Common;
import net.ib.mntalk.protocol.Common.BuddyInfo;
import net.ib.mtalk.R;
import net.ib.mtalk.base.BaseFragmentActivity;
import net.ib.mtalk.constant.HandlerMsgConst;
import net.ib.mtalk.database.DatabaseContract.BuddyTable;
import net.ib.mtalk.database.DatabaseContract.ContactTable;
import net.ib.mtalk.database.helper.NotifyingAsyncQueryHandler;
import net.ib.mtalk.global.GlobalPreferences;
import net.ib.mtalk.test.TestSessionServer;
import net.ib.mtalk.ui.ActivityResult;
import net.ib.mtalk.ui.buddy.BuddyTabActivity;
import net.ib.mtalk.ui.buddy.item.BuddyActionItem;
import net.ib.mtalk.ui.buddy.item.BuddyActionItem.ItemType;
import net.ib.mtalk.ui.buddy.talk.BuddyTalkListActivity;
import net.ib.mtalk.ui.setting.SettingsActivity;
import net.ib.mtalk.ui.widget.QuickAction;
import net.ib.mtalk.util.MTalkLogWriter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognizerIntent;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;

import com.google.protobuf.micro.InvalidProtocolBufferMicroException;

public class FavoriteActivity extends BaseFragmentActivity{
	private static Context mContext;
	public LinearLayout buddyTabLayout;
	
	private static final int MENU_SETTING = 1;
	
	private static NotifyingAsyncQueryHandler queryHandler;
	private FavoriteController mUiController;
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			switch(msg.what){
			case HandlerMsgConst.HANDLER_ALL_ADD_CONTACTS_SUCCESS:
				Toast.makeText(mContext, "HANDLER_ALL_ADD_CONTACTS_SUCCESS", Toast.LENGTH_SHORT).show();
				break;
			case HandlerMsgConst.HANDLER_ALL_ADD_CONTACTS_FAIL:
				Toast.makeText(mContext, "HANDLER_ALL_ADD_CONTACTS_FAIL", Toast.LENGTH_SHORT).show();
				break;
			case HandlerMsgConst.HANDLER_UNKNOWN_ERROR:
				Toast.makeText(mContext, "HANDLER_UNKNOWN_ERROR", Toast.LENGTH_SHORT).show();
				break;
			}
		};
	};
	private static EditText searchBuddy;
	private ImageButton voice_btn;
	FavoriteFragment list;
	private static final int QUERY_FAVORITE = 0;
	private static final int REQ_CODE_VOICE_RECOGNITION = 100;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_buddy_contact_list);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		
		mContext = this;
		mUiController = new FavoriteController(mContext, mHandler);
		FragmentManager fm = getSupportFragmentManager();
		
		if(savedInstanceState == null){
			list = new FavoriteFragment();
			fm.beginTransaction().add(R.id.buddy_talk_list, list).commit();
		}
		
		searchBuddy = (EditText)findViewById(R.id.buddy_search);
		searchBuddy.addTextChangedListener(watcher());
		// 보이스 검색
		voice_btn = (ImageButton) findViewById(R.id.buddy_voice_btn);
		voice_btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
				intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
				intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.buddy_voice_recognition));
				startActivityForResult(intent, REQ_CODE_VOICE_RECOGNITION);
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, MENU_SETTING, 20, R.string.settings).setIcon(R.drawable.menu_icon_settings);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch(item.getItemId()){
			case MENU_SETTING :
				Intent intent = new Intent(this, SettingsActivity.class);
				startActivity(intent);
				break;
		}
		return super.onMenuItemSelected(featureId, item);
	}
	
	public static class FavoriteFragment extends ListFragment{
		private CursorAdapter mAdapter;
		private List<Integer> arr_group = new ArrayList<Integer>();
		
		public static final char HANGUL_BEGIN_UNICODE = 44032; // 가
		public static final char HANGUL_END_UNICODE = 55203; // 힣
		public static final char HANGUL_BASE_UNIT = 588;//각자음 마다 가지는 글자수
		public static final char[] INITIAL_SOUND = { 'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ',
	        'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' };
		
		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
			super.onActivityCreated(savedInstanceState);
			setHasOptionsMenu(true);
			
			mAdapter = new FavoriteListCursorAdapter(getActivity().getParent(),
					null, 0, arr_group);
			
			ListView listView = getListView();
			listView.setDivider(getResources().getDrawable(R.drawable.inbox_divider));
			listView.setDividerHeight(1);
			listView.setFastScrollEnabled(true);
			listView.setScrollingCacheEnabled(false);
			listView.setAdapter(mAdapter);
			
			queryHandler = new NotifyingAsyncQueryHandler(getActivity().getParent().getContentResolver(), onQueryReturn);
			String select = "(" + BuddyTable.KEY_BUDDY_FAVORITE + "='1' AND " 
				+ BuddyTable.KEY_BUDDY_STATUS_TYPE + "=" + Common.BUDDY_STATUS_NORMAL + " AND " 
				+ "((" + BuddyTable.KEY_BUDDY_CHOSUNG + " LIKE ?) OR (" + BuddyTable.KEY_BUDDY_DISPLAYNICK + " LIKE ?)" + "))";
			String sortOrder = BuddyTable.KEY_BUDDY_DISPLAYNICK + " COLLATE LOCALIZED ASC";
			queryHandler.startQuery(QUERY_FAVORITE, null, BuddyTable.CONTENT_URI, BuddyTable.PROJECTION, select, 
					new String[]{"%" + searchBuddy.getText().toString() + "%", "%" + searchBuddy.getText().toString() + "%"}, sortOrder);
		}
		
		// 아이템 클릭 이벤트
		@Override
		public void onListItemClick(ListView l, View v, int position, long id) {
			super.onListItemClick(l, v, position, id);
			Cursor cursor = (Cursor)l.getItemAtPosition(position);
			int buddy_id = cursor.getInt(cursor.getColumnIndexOrThrow(BuddyTable._ID));
			long receiverMsb = cursor.getLong(cursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_UUID_MSB));
			long receiverLsb = cursor.getLong(cursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_UUID_LSB));
			String displayName  = cursor.getString(cursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_DISPLAYNAME));
			int favorite = cursor.getInt(cursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_FAVORITE));
			
			String selection = ContactTable.KEY_BUDDY_UUID_MSB + "=? AND " + ContactTable.KEY_BUDDY_UUID_LSB + "=?";
			String[] selectionArgs = {String.valueOf(receiverMsb), String.valueOf(receiverLsb)};
			Cursor cursor2 = mContext.getContentResolver().query(ContactTable.CONTENT_URI, new String[] {ContactTable.KEY_CONTACT_PHONE_ID},
							selection, selectionArgs, null);
			// 연락처 소유 구분
			int raw_id = -1;
			try{
				while(cursor2.moveToNext()){
					raw_id = cursor2.getInt(cursor2.getColumnIndexOrThrow(ContactTable.KEY_CONTACT_PHONE_ID));
				}
			} finally{
				cursor2.close();
			}
			
			BuddyInfo buddyInfo = null;
			try {
				buddyInfo = BuddyInfo.parseFrom(cursor.getBlob(cursor.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_INFO)));
			} catch (InvalidProtocolBufferMicroException e1) {
				e1.printStackTrace();
			} catch (IllegalArgumentException e1) {
				e1.printStackTrace();
			}
			goQuickAction(v, buddy_id, receiverMsb, receiverLsb, displayName, buddyInfo , raw_id, favorite);
		}
		/**
		 * 현재 Favorite 변화 상태를 Observing 한다. 
		 */
		static ContentObserver mFavoriteObserver = new ContentObserver(new Handler()) {
			public void onChange(boolean selfChange) {
				String select = "(" + BuddyTable.KEY_BUDDY_FAVORITE + "='1' AND " 
					+ BuddyTable.KEY_BUDDY_STATUS_TYPE + "=" + Common.BUDDY_STATUS_NORMAL + " AND " 
					+ "((" + BuddyTable.KEY_BUDDY_CHOSUNG + " LIKE ?) OR (" + BuddyTable.KEY_BUDDY_DISPLAYNICK + " LIKE ?)" + "))";
				String sortOrder = BuddyTable.KEY_BUDDY_DISPLAYNICK + " COLLATE LOCALIZED ASC";
				queryHandler.startQuery(QUERY_FAVORITE, null, BuddyTable.CONTENT_URI, BuddyTable.PROJECTION, select, 
						new String[]{"%" + searchBuddy.getText().toString() + "%", "%" + searchBuddy.getText().toString() + "%"}, sortOrder);
			};
		};
		

		private void goQuickAction(View v, int buddy_id, long receiverMsb, long receiverLsb, String displayName, BuddyInfo buddyInfo, int raw_id, int favorite) {
			try {
				// 액션 바를 띄워준다.
				QuickAction quickAction = new QuickAction(v.findViewById(R.id.buddy_child_profile));
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.ONE_TO_ONE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
				if(raw_id != -1){
					quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.SEND_MESSAGE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
					quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.CALL, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
				}
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.PROFILEVIEW, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.FAVORITE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
//				quickAction.addActionItem(new BuddyActionItem(mContext, ItemType.INVITE, buddy_id, receiverMsb, receiverLsb, buddyInfo, displayName, raw_id, favorite, quickAction));
				quickAction.setAnimStyle(QuickAction.ANIM_AUTO);
				quickAction.setMode(QuickAction.MODE_DIALOG);
				quickAction.show();
			} catch (IllegalArgumentException e) {
				MTalkLogWriter.e(e);
			}
		}
		
		@Override
		public void onResume() {
			super.onResume();
			searchBuddy.addTextChangedListener(watcher());
			getActivity().getParent().getApplicationContext().getContentResolver().registerContentObserver(BuddyTable.CONTENT_URI, true, mFavoriteObserver);
			mFavoriteObserver.onChange(true);
		}

		@Override
		public void onPause() {
			super.onPause();
			searchBuddy.removeTextChangedListener(watcher());
			getActivity().getParent().getApplicationContext().getContentResolver().unregisterContentObserver(mFavoriteObserver);
			((InputMethodManager)getActivity().getParent().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchBuddy.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 

		}

		private void makeNameTag(Cursor data) {
			ArrayList<Character> char_group = new ArrayList<Character>();
			arr_group.clear();
			data.moveToFirst();
			data.moveToPrevious();	
			while(data.moveToNext()){	// 0번째부터 다시 NameTag 생성
				 /** 초성을 판별하여 인덱스 생성*/
		        String a = data.getString(data.getColumnIndexOrThrow(BuddyTable.KEY_BUDDY_DISPLAYNICK));
		        if(a == null || "".equals(a)){
		        	a = " ";
		        }
		        char b = a.charAt(0);
		        char d;
		        if(b < HANGUL_BEGIN_UNICODE){
		        	d = b;
		        } else{
		        	d = INITIAL_SOUND[(b-HANGUL_BEGIN_UNICODE)/HANGUL_BASE_UNIT];
		        }
		        
		        if(!char_group.contains(d)) {
		        	char_group.add(d);
		        	if(!arr_group.contains(data.getPosition())) arr_group.add(data.getPosition());
		        }
			}
		}
		
		NotifyingAsyncQueryHandler.AsyncQueryListener onQueryReturn = new NotifyingAsyncQueryHandler.AsyncQueryListener() {
			@Override
			public void onQueryComplete(int token, Object cookie, Cursor cursor) {
				switch (token){
				case QUERY_FAVORITE:
					getActivity().getParent().startManagingCursor(cursor);
					mAdapter.changeCursor(cursor);
					makeNameTag(cursor);
//					Cursor cursor1 = mContext.getContentResolver().query(BuddyTable.CONTENT_URI, BuddyTable.PROJECTION, 
//							BuddyTable.KEY_BUDDY_NEW_FRIEND + "=1 AND " + BuddyTable.KEY_BUDDY_STATUS_TYPE + "=1", null, null);
//					BuddyTabActivity.updateMnTalkBadge(cursor1.getCount());
//					cursor1.close();
					break;
				}
			}
			
			@Override
			public void onUpdateComplete(int token, Object cookie, int result) {
			}
			
			@Override
			public void onInsertComplete(int token, Object cookie, Uri uri) {
			}
			
			@Override
			public void onDeleteComplete(int token, Object cookie, int result) {
			}
		};
	}

	public static TextWatcher watcher(){
		TextWatcher textWatcher = new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) {
			}
			
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,	int after) {
			}
			
			@Override
			public void afterTextChanged(Editable s) {
				FavoriteFragment.mFavoriteObserver.onChange(true);
			}
		};
		return textWatcher;
	}
	
	
	/**
	 * onActivityResult() 는 이 인자 세트를 세팅한 후 즉시 종료해야 한다.
	 * onResume() 마지막에서는 이 정보를 이용하여 작업을 진행한 후, 즉시 인자 세트를 폐기한다.
	 */
	ActivityResult mActivityResult = null;

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
		super.onActivityResult(requestCode, resultCode, intent);
		mActivityResult = new ActivityResult(requestCode, resultCode, intent);
	}

	/**
	 * onActivityResult() 에서 하고자 하는 작업을 이 함수에 구현한다.
	 * @param requestCode onActivityResult()에서 저장해뒀던 내용
	 * @param resultCode 위와 같음
	 * @param intent 위와 같음
	 * @see ActivityResult
	 */
	protected void handleActivityResult(int requestCode, int resultCode, Intent intent) {
		if (resultCode != Activity.RESULT_OK) {
			return;
		}
		switch (requestCode) {
		case REQ_CODE_VOICE_RECOGNITION:
			ArrayList<String> matches = intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
			searchBuddy.setText(searchBuddy.getText() + matches.get(0));
			break;
		default:
			break;
		}
	}
	@Override
	public void onResume() {
		super.onResume();
		if (mActivityResult != null) {
			handleActivityResult(mActivityResult.getRequestCode(), mActivityResult.getResultCode(), mActivityResult.getIntent());
			mActivityResult = null;	// 반드시 있어야 함
		}
	}
}
